<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  
  
  <link rel="shortcut icon" href="img/favicon.ico">
  <title>Stream - Java Note</title>
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700" />

  <link rel="stylesheet" href="css/theme.css" />
  <link rel="stylesheet" href="css/theme_extra.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" />
  
  <script>
    // Current page data
    var mkdocs_page_name = "Stream";
    var mkdocs_page_input_path = "Stream.md";
    var mkdocs_page_url = null;
  </script>
  
  <script src="js/jquery-2.1.1.min.js" defer></script>
  <script src="js/modernizr-2.8.3.min.js" defer></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
  <script>hljs.initHighlightingOnLoad();</script> 
  
</head>

<body class="wy-body-for-nav" role="document">

  <div class="wy-grid-for-nav">

    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
    <div class="wy-side-scroll">
      <div class="wy-side-nav-search">
        <a href="." class="icon icon-home"> Java Note</a>
        <div role="search">
  <form id ="rtd-search-form" class="wy-form" action="./search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" title="Type search term here" />
  </form>
</div>
      </div>

      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="index.html">Home</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="StringX.html">StringX</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="Collection.html">Collection</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="IO.html">IOFile</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="Lambda.html">Lambda</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="Generic.html">Generic</a>
                    </li>
                </ul>
                <ul class="current">
                    <li class="toctree-l1 current"><a class="reference internal current" href="Stream.html">Stream</a>
    <ul class="current">
    <li class="toctree-l2"><a class="reference internal" href="#_1">创建</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#streamof">Stream.of</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#arraysstream">Arrays.stream</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#collectionparallelsstream">Collection.(parallelS|s)tream()</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#intstreamrange">IntStream.range</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#randomints">Random.ints</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#streamgenerate">Stream.generate</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#other-operations">Other Operations</a>
    </li>
        </ul>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#_2">操作</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#intermediate">Intermediate</a>
        <ul>
    <li class="toctree-l4"><a class="reference internal" href="#filter">filter</a>
    </li>
    <li class="toctree-l4"><a class="reference internal" href="#map">map</a>
    </li>
        </ul>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#terminal">Terminal</a>
        <ul>
    <li class="toctree-l4"><a class="reference internal" href="#reduce">reduce</a>
    </li>
        </ul>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#short-circuiting">short-circuiting</a>
        <ul>
    <li class="toctree-l4"><a class="reference internal" href="#anymatch">anyMatch()</a>
    </li>
    <li class="toctree-l4"><a class="reference internal" href="#findfirst">findFirst()</a>
    </li>
        </ul>
    </li>
        </ul>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#_3">可并行</a>
    </li>
    </ul>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="Atomic.html">Atomic</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="Reflect.html">Reflect</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="JavaFX.html">JavaFX</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="Sundry.html">Sundry</a>
                    </li>
                </ul>
      </div>
    </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
        <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
        <a href=".">Java Note</a>
      </nav>

      
      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="breadcrumbs navigation">
  <ul class="wy-breadcrumbs">
    <li><a href=".">Docs</a> &raquo;</li>
    
      
    
    <li>Stream</li>
    <li class="wy-breadcrumbs-aside">
      
    </li>
  </ul>
  
  <hr/>
</div>
          <div role="main">
            <div class="section">
              
                <h2 id="stream">Stream</h2>
<blockquote>
<p><strong>Java <code>interface</code> 的静态方法可以直接写实现</strong></p>
<p>非静态可以写 <code>default</code></p>
</blockquote>
<h3 id="_1">创建</h3>
<h4 id="streamof">Stream.of</h4>
<pre><code class="language-java">import java.util.stream.Stream;

public class StreamBuilders
{
    public static void main(String[] args)
    {
        //直接使用 Stream 接口创建
        Stream&lt;Integer&gt; stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
        //public static&lt;T&gt; Stream&lt;T&gt; of(T... values) { return Arrays.stream(values); }
        stream.forEach(p -&gt; System.out.println(p));
    }
}
</code></pre>
<h4 id="arraysstream">Arrays.stream</h4>
<p>其实和上面那个是一样的，Stream 的 of 方法就是封装的 <code>Arrays.stream</code> 方法</p>
<pre><code class="language-java">import java.util.Arrays;
import java.util.stream.Stream;

public class StreamBuilders
{
    public static void main(String[] args)
    {
        Stream&lt;Integer&gt; stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9});
        stream.forEach(p -&gt; System.out.println(p));
    }
}
</code></pre>
<h4 id="collectionparallelsstream">Collection.(parallelS|s)tream()</h4>
<pre><code class="language-java">import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamBuilders
{
    public static void main(String[] args)
    {
        List&lt;Integer&gt; list = 
            new ArrayList&lt;Integer&gt;(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }));

        Stream&lt;Integer&gt; stream = list.stream();    //or list.parallelStream();
        stream.forEach(p -&gt; System.out.println(p));
    }
}
</code></pre>
<h4 id="intstreamrange">IntStream.range</h4>
<pre><code class="language-java">import java.util.stream.IntStream;

public class StreamBuilders
{
    public static void main(String[] args)
    {
        IntStream stream = IntStream.range(1, 9);//[1,9)
        stream.forEach(p -&gt; System.out.println(p));
    }
}
</code></pre>
<h4 id="randomints">Random.ints</h4>
<pre><code class="language-java">import java.util.Random;
import java.util.stream.IntStream;

public class StreamBuilders
{
    public static void main(String[] args)
    {
        IntStream stream = new Random().ints(1, 10);//[1,10)
        //该流不会终止
        stream.forEach(p -&gt; System.out.println(p));
    }
}
</code></pre>
<h4 id="streamgenerate">Stream.generate</h4>
<pre><code class="language-java">import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

public class StreamBuilders
{
    static int i = 0;
    public static void main(String[] args)
    {
        Stream&lt;Integer&gt; stream = Stream.generate(() -&gt; {
            try
            {
                TimeUnit.SECONDS.sleep(1);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            return i++;
        });
        stream.forEach(p -&gt; System.out.println(p));// 不会终止的流
    }
}
</code></pre>
<h4 id="other-operations">Other Operations</h4>
<table>
<thead>
<tr>
<th>Method</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>collect(Collectors.toList())</td>
<td></td>
</tr>
<tr>
<td>toArray(EntryType[]::new)</td>
<td></td>
</tr>
</tbody>
</table>
<h3 id="_2">操作</h3>
<h4 id="intermediate">Intermediate</h4>
<p>惰性操作 </p>
<table>
<thead>
<tr>
<th>Method</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>filter</code></td>
<td>过滤元素</td>
</tr>
<tr>
<td><code>map</code></td>
<td>元素映射 修改</td>
</tr>
<tr>
<td><code>sorted</code></td>
<td>排序 可以自定义接口</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>api</th>
<th align="left">description</th>
<th align="left">function</th>
<th align="left">code</th>
</tr>
</thead>
<tbody>
<tr>
<td>filter</td>
<td align="left">Returns a stream consisting of the elements of this stream that match the given predicate.</td>
<td align="left">过滤器，将不需要的内容过滤掉，只留下我们想要的数据</td>
<td align="left"></td>
</tr>
<tr>
<td>map</td>
<td align="left">Returns a stream consisting of the results of applying the given function to the elements of this stream</td>
<td align="left">将数据转换为另外一种格式的操作，比如我们可以将String类型的数据转换为全是大写字母的String</td>
<td align="left"></td>
</tr>
<tr>
<td>mapToInt</td>
<td align="left">Returns an {@code IntStream} consisting of the results of applying the given function to the elements of this stream.</td>
<td align="left">属于map，但是更为具体，指定了将要转换达到的类型设定为int，同类型的还有mapToLong,maptoDouble，下面不再叙述</td>
<td align="left">integerStream.mapToInt(value -&gt; value + 100);</td>
</tr>
<tr>
<td>flatMap</td>
<td align="left">Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.  Each mapped stream is {@link java.util.stream.BaseStream#close() closed} after its contents have been placed into this stream.  (If a mapped stream is {@code null} an empty stream is used, instead.)</td>
<td align="left">map操作达到的效果是一对一的，也就是只会生成一个转换后的元素，而flatMap则是一对多的，使得对每一个上游元素，你都可以生成一个新的Stream，这种处理模式将底层数据扁平化，后面的代码展示了如何使用flatMap</td>
<td align="left">integerStream.flatMap((Function&lt;Integer, Stream&lt;?&gt;&gt;) integer -&gt; Stream.of(integer));</td>
</tr>
<tr>
<td>flatMapToLong</td>
<td align="left">*</td>
<td align="left">更加具体的指定了需要转换成的数据类型，此操作希望将上游的每一个元素都转换为一个LongStream，榆次类似的还要flatMapToInt、flatMapToDoble，下文中不再叙述</td>
<td align="left">integerStream.flatMapToLong(integer -&gt; LongStream.of(integer));</td>
</tr>
<tr>
<td>distinct</td>
<td align="left">*</td>
<td align="left">这是比较常用的操作，可以对元素类型去重，Stream使用HashSet来实现去重</td>
<td align="left"></td>
</tr>
<tr>
<td>sorted</td>
<td align="left">*</td>
<td align="left">排序，使用自然排序</td>
<td align="left">Stream.of(arrays).sorted().forEach(System.out::println);</td>
</tr>
<tr>
<td>sorted(Com[arator)</td>
<td align="left">*</td>
<td align="left">带参数的排序操作，参数由你指定排序的规则</td>
<td align="left"></td>
</tr>
<tr>
<td>limit</td>
<td align="left">Returns a stream consisting of the elements of this stream, truncated to be no longer than {@code maxSize} in length.</td>
<td align="left">用于限流，Stream最多只会取limit设定的元素个数到下游</td>
<td align="left">Stream.of(1,2,3,4,5).limit(2).forEach(System.out::println);</td>
</tr>
<tr>
<td>skip</td>
<td align="left">*</td>
<td align="left">和limit类似，但是skip是跳过前几个元素，然后再将接下来的元素传送到下游操作</td>
<td align="left"></td>
</tr>
</tbody>
</table>
<h5 id="filter">filter</h5>
<pre><code class="language-java">import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamBuilders
{
    public static void main(String[] args)
    {
        List&lt;String&gt; list = new ArrayList&lt;String&gt;(Arrays.asList(new String[]{ 
                    &quot;Amitabh&quot;, &quot;Shekhar&quot;, &quot;Aman&quot;, &quot;Rahul&quot;, 
                    &quot;Shahrukh&quot;, &quot;Salman&quot;, &quot;Yana&quot;, &quot;Lokesh&quot;}));

        Stream&lt;String&gt; stream = list.stream();

        stream.filter((s) -&gt; s.startsWith(&quot;A&quot;)).forEach(System.out::println);// 保留 A 开头的字符串
    }
}
</code></pre>
<h5 id="map">map</h5>
<pre><code class="language-java">import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamBuilders
{
    public static void main(String[] args)
    {
        List&lt;String&gt; list = new ArrayList&lt;String&gt;(Arrays.asList(new String[]{ 
                    &quot;Amitabh&quot;, &quot;Shekhar&quot;, &quot;Aman&quot;, &quot;Rahul&quot;, 
                    &quot;Shahrukh&quot;, &quot;Salman&quot;, &quot;Yana&quot;, &quot;Lokesh&quot;}));

        Stream&lt;String&gt; stream = list.stream();

        stream.filter((s) -&gt; s.startsWith(&quot;A&quot;)).map(String::toUpperCase).forEach(System.out::println);
    }
}
</code></pre>
<h4 id="terminal">Terminal</h4>
<table>
<thead>
<tr>
<th>Method</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>forEach</code></td>
<td>迭代元素</td>
</tr>
<tr>
<td><code>collect</code></td>
<td>得到集合</td>
</tr>
<tr>
<td><code>match</code></td>
<td>匹配判断 <code>(any|all|none)Match</code></td>
</tr>
<tr>
<td><code>reduce</code></td>
<td>元组组合操作</td>
</tr>
<tr>
<td><code>count/min/max</code></td>
<td>计数</td>
</tr>
</tbody>
</table>
<p>唯一操作</p>
<h5 id="reduce">reduce</h5>
<pre><code class="language-java">import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class StreamBuilders
{
    public static void main(String[] args)
    {
        List&lt;String&gt; list = new ArrayList&lt;String&gt;(Arrays.asList(new String[]{ 
                    &quot;Amitabh&quot;, &quot;Shekhar&quot;, &quot;Aman&quot;, &quot;Rahul&quot;, 
                    &quot;Shahrukh&quot;, &quot;Salman&quot;, &quot;Yana&quot;, &quot;Lokesh&quot;}));

        Optional&lt;String&gt; reduced = list.stream().reduce((s1, s2) -&gt; s1 + &quot;#&quot; + s2);

        reduced.ifPresent(System.out::println);

        //打印结果：Amitabh#Shekhar#Aman#Rahul#Shahrukh#Salman#Yana#Lokesh
    }
}
</code></pre>
<h4 id="short-circuiting">short-circuiting</h4>
<h5 id="anymatch"><strong>anyMatch()</strong></h5>
<p><strong>返回布尔值，只要找到一个匹配的元素，就停止接下来的元素遍历</strong></p>
<p><code>boolean matched = list.stream().anyMatch((s) -&gt; s.startsWith("A"));</code></p>
<h5 id="findfirst"><strong>findFirst()</strong></h5>
<p><strong>返回元素，同样，只返回第一个元素，不会全部遍历</strong></p>
<p><code>String firstMatchedName = list.stream().filter((s) -&gt; s.startsWith("L")).findFirst().get();</code></p>
<table>
<thead>
<tr>
<th>api</th>
<th align="left">description</th>
<th align="left">function</th>
<th align="left">code</th>
</tr>
</thead>
<tbody>
<tr>
<td>anyMatch</td>
<td align="left"></td>
<td align="left">任意元素满足即可</td>
<td align="left">Stream.of(1,2,3,4,5).anyMatch(integer -&gt; integer % 2 == 0);</td>
</tr>
<tr>
<td>allMatch</td>
<td align="left"></td>
<td align="left">所有元素都需要满足</td>
<td align="left">Stream.of(1, 2, 3).allMatch(integer -&gt; integer &gt; 2);</td>
</tr>
<tr>
<td>noneMatch</td>
<td align="left"></td>
<td align="left">所有元素都不满足</td>
<td align="left">Stream.of(1,2,3).noneMatch(integer -&gt; integer % 2 == 0);</td>
</tr>
<tr>
<td>findFirst</td>
<td align="left"></td>
<td align="left">返回Stream的第一个元素或者空</td>
<td align="left"></td>
</tr>
<tr>
<td>findAny</td>
<td align="left"></td>
<td align="left">返回任何一个元素然后就结束了</td>
<td align="left"></td>
</tr>
<tr>
<td>limit</td>
<td align="left"></td>
<td align="left">上文已经说过</td>
<td align="left"></td>
</tr>
</tbody>
</table>
<h3 id="_3">可并行</h3>
<h2 id="optional">Optional</h2>
<p>实现了类似 <strong>Stream API</strong> 的操作</p>
              
            </div>
          </div>
          <footer>
  
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="Atomic.html" class="btn btn-neutral float-right" title="Atomic">Next <span class="icon icon-circle-arrow-right"></span></a>
      
      
        <a href="Generic.html" class="btn btn-neutral" title="Generic"><span class="icon icon-circle-arrow-left"></span> Previous</a>
      
    </div>
  

  <hr/>

  <div role="contentinfo">
    <!-- Copyright etc -->
    
  </div>

  Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
      
        </div>
      </div>

    </section>

  </div>

  <div class="rst-versions" role="note" aria-label="versions">
    <span class="rst-current-version" data-toggle="rst-current-version">
      
      
        <span><a href="Generic.html" style="color: #fcfcfc;">&laquo; Previous</a></span>
      
      
        <span style="margin-left: 15px"><a href="Atomic.html" style="color: #fcfcfc">Next &raquo;</a></span>
      
    </span>
</div>
    <script>var base_url = '.';</script>
    <script src="js/theme.js" defer></script>
      <script src="search/main.js" defer></script>
    <script defer>
        window.onload = function () {
            SphinxRtdTheme.Navigation.enable(true);
        };
    </script>

</body>
</html>
